home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NeXT Education Software Sampler 1992 Fall
/
NeXT Education Software Sampler 1992 Fall.iso
/
SoundAndMusic
/
cmix
/
filters
/
filter.f
< prev
next >
Wrap
Text File
|
1988-10-09
|
23KB
|
315 lines
implicit real*8 (a-h,o-z)
real*4 x1,x2,x3,x4,x5
common/b/cn(30),cd(30),mn,md,const
call reset
write(6,1000)
1000 format( ' '/
&' f3=0-> low or highpass. f1=passband cutoff. f2=stopband cutoff'/
&' f1<f2 -> lowpass.'/
&' f3>0 -> bandpass. f1,f2 are limits of passband. f3 is limit of'/
&' either high or low stopband._ we require f1<f2.'/
&' ripple=passband ripple in db. atten=stopband attenuation in db.'
&)
write(6,910)
910 format( ' the filter coefficients will be found in a file called
$ fort.7'/
$' the listing of the program output will be found in fort.8'/
$ ' enter the following arguments in floating point form.')
write(6,900)
900 format( ' enter sampling rate.')
read(5,901) sr
901 format(g10.0)
xnyq=sr/2.d0
write(6,903)
903 format( ' enter f1')
read( 5,901) x1
write(6,905)
905 format( ' enter f2')
read( 5,901) x2
write(6,906)
906 format( ' enter f3')
read( 5,901) x3
write(6,907)
907 format( ' enter ripple')
read( 5,901) x4
write(6,908)
908 format( ' enter attenuation in db')
read( 5,901) x5
c write(8,98) x1,x2,x3,x4,x5
write(6,97) x1,x2,x3,x4,x5
c98 format( ' f1=',f8.3,' f2=',f8.3,' f3=',f8.3,' ripple=',
c $f8.3,' atten=',f8.3)
97 format('c f1=',f8.3,' f2=',f8.3,' f3=',f8.3,' ripple=',
$f8.3,' atten=',f8.3)
f1=x1
f2=x2
f3=x3
ripple=x4
atten=x5
call ellips(f1,f2,f3,ripple,atten,sr)
call fresp(200,sr,0.d0,xnyq,f1)
m2=mn/2
write(7,1234) m2,x1,x2,x3,x4,x5
1234 format('/*elliptical filter with',i3,' sections.'/
&'f1,f2,f3=',3g10.4,' ripple=',g10.4,' db=',g10.4,'*/')
write(7,899) m2,(cn(i),cd(i),i=1,mn)
899 format('ell(start,dur,inskip,chin,chout,',i3,',',4(g15.8,','))
write(7,898) const
898 format(e15.8,')')
stop
end
subroutine reset
implicit real*8 (a-h,o-z)
common/b/cn(30),cd(30),mn,md,const
mn=0
md=0
write(8,200)
200 format('//')
do 100 m=1,30
cn(m)=0.
cd(m)=0.
100 continue
return
end
subroutine ellips(f1,f2,f3,ripple,atten,samr)
c designs an elliptic filter. all parameters real*8 .
c f3=0 -> lowpass or highpass. f1=passband cutoff. f2=stopband cutoff.
c f1<f2 -> lowpass.
c f3>0 -> bandpass. f1,f2 are limits of passband. f3 is limit of
c either high or low stopband. we require f1<f2.
c ripple=passband ripple in db. atten=stopband attenuation in db.
c samr=sampling rate in hz.
c after gold+rader; written by bilofsky, revised by steiglitz
c pp.61-65 (elliptic filters), 72,76 (mappings
c from s-plane to z-plane), 87 (approximation
c for u0 and evaluation of elliptic functions).
implicit real*8 (a-h,o-z)
real*8 k,k1,kay,kprime,k1prim ,nn,kk,kkp,kk1,kk1p
common/ellipt/k,kprime,cosp0,w1,hpass
prime(dummy)=dsqrt(1.d0-dummy**2)
bpt(w)=dabs((cosp0-dcos(w))/dsin(w))
pi=3.14159265358979d0
w1=2.d0*pi*f1/samr
w2=2.d0*pi*f2/samr
w3=2.d0*pi*f3/samr
hpass=0.d0
cosp0=0.d0
if(f3.gt.0.d0)goto1
if(f1.lt.f2)goto2
c modify frequencies for high pass.
w1=pi-w1
w2=pi-w2
hpass=1.d0
c compute analog frequencies for low/high pass
2 w1=dtan(.5d0*w1)
w2=dtan(.5d0*w2)
goto3
c compute analog frequencies for band pass.
1 cosp0=dcos((w1+w2)/2.d0)/dcos((w1-w2)/2.d0)
w1=bpt(w1)
de=w3-w2
if (de.lt.0.d0) de=w1-w3
w2=dmin1(bpt(w1-de),bpt(w2+de))
c compute params for poles,zeros in lambda plane
3 k=w1/w2
kprime=prime(k)
eps=dsqrt(10.d0**(.1d0*ripple)-1.d0)
a=10.d0**(.05d0*atten)
k1=eps/dsqrt(a*a-1.d0)
k1prim =prime(k1)
kk=kay(k)
kk1=kay(k1)
kkp=kay(kprime)
kk1p=kay(k1prim )
n=idint(kk1p*kk/(kk1*kkp))+1
nn=n
5 u0=-kkp*dlog((1.d0+dsqrt(1.d0+eps*eps))/eps)/kk1p
c now compute poles,zeros in lambda plane,
c transform one by one to z plane.
dd=kk/nn
tt=kk-dd
dd=dd+dd
n2=(n+1)/2
do 4 i=1,n2
if (i*2.gt.n) tt=0.d0
call stuff1(-kkp,tt,'zero')
call stuff1(u0,tt,'pole')
4 tt=tt-dd
return
end
subroutine stuff1(q,r,whatsi )
c transforms poles and zeros to z-plane; stuffs coeff. array
implicit real*8 (a-h,o-z)
real*8 k,kprime
common/b/cn(30),cd(30),mn,md,const
character*4 whatsi
complex*16 dcmplx,cdsqrt,dconjg,z,s
common/ellipt/k,kprime,cosp0,w1,hpass
call djelf(snr,cnr,dnr,r,kprime*kprime)
call djelf(snqp,cnqp,dnqp,q,k*k)
omega=1-snqp*snqp*dnr*dnr
if ( omega .eq. 0.d0 ) omega=1.d-30
sigma=w1*snqp*cnqp*cnr*dnr/omega
omega=w1*snr*dnqp/omega
s=dcmplx(sigma,omega)
j=1
if (cosp0.eq.0.d0) goto 1
j=-1
4 z=(-cosp0+dfloat(j)*cdsqrt(cosp0*cosp0+s*s-1.d0))/(s-1.d0)
go to 3
1 z=(1.d0+s)/(1.d0-s)
if(hpass.ne.0.d0)z=-z
3 if(dabs(dimag(z)).le.10.d-10) goto 2
if(dimag(z).lt.0.d0) z=dconjg(z)
if(whatsi.eq.'pole')goto5
mn=mn+1
cn(mn)=-2.d0*dreal(z)
mn=mn+1
cn(mn)=dreal(z)**2+dimag(z)**2
goto6
5 md=md+1
cd(md)=-2.d0*dreal(z)
md=md+1
cd(md)=dreal(z)**2+dimag(z)**2
6 write(8,202)whatsi,z
202 format(' complex ',a4,' pair at ',d17.9,' +-j',d17.9)
if(j.gt.0.or.r.eq.0.d0)return
j=1
go to 4
2 x=dreal(z)
if(whatsi.eq.'pole')goto7
mn=mn+1
cn(mn)=-x
mn=mn+1
cn(mn)=0.d0
goto8
7 md=md+1
cd(md)=-x
md=md+1
cd(md)=0.d0
8 write(8,201)whatsi,x
201 format(' real ',a4,' at ',d17.9)
if(j.gt.0) return
j=1
go to 4
end
subroutine fresp(k,samr,f1,f2,f3)
c plots k pts. of freq. resp. from f1 to f2, norm. at f3
implicit real*8 (a-h,o-z)
complex*16 dcmplx,cdexp,tf,zm,zm2
common/b/cn(30),cd(30),mn,md,const
pi=3.14159265358979d0
m2=mn/2
write(8,200)m2,(cn(i),cd(i),i=1,mn)
200 format('elliptic filter with ',i5,' sections'/4(d17.9))
w=pi*f3/(.5d0*samr)
zm=cdexp(dcmplx(0.d0,-1.d0*w))
zm2=zm*zm
tf=(1.d0,0.d0)
do 1 i=1,mn,2
1 tf=tf*(1.d0+cn(i)*zm+cn(i+1)*zm2)/(1.d0+cd(i)*zm+cd(i+1)*zm2)
const=1.d0/cdabs(tf)
write(8,201)const
201 format(' const=',d17.9)
write(8,205)
205 format('/ freq phase',10x,' amp',10x,' db.')
do 3 j=1,k
freq=f1+(f2-f1)*dfloat(j-1)/dfloat(k-1)
w=pi*freq/(.5d0*samr)
zm=cdexp(dcmplx(0.d0,-1.d0*w))
zm2=zm*zm
tf=dcmplx(const,0.d0)
do 2 i=1,mn,2
2 tf=tf*(1.d0+cn(i)*zm+cn(i+1)*zm2)/(1.d0+cd(i)*zm+cd(i+1)*zm2)
amp=cdabs(tf)
if(amp.le.1.d-20)amp=1.d-20
x=dreal(tf)
y=dimag(tf)
phase=0.d0
if(x.eq.0.d0 .and. y.eq.0.d0)goto4
phase=(180.d0/pi)*datan2(y,x)
4 db=20.d0*dlog10(dmax1(amp,1.d-40))
3 write(8,202)freq,phase,amp,db
202 format(' ',f10.2,2d17.9,f12.4)
return
end
double precision function kay(k)
c computes kay(k)=inverse sn(1)
c hastings, approx. for dig. comp., p. 172
implicit real*8 (a-h,o-z)
double precision k,eta,peta,kk
dimension a(5),b(5)
data a/1.38629436112d0, .09666344259d0, .03590092383d0,
1 .03742563713d0, .01451196212d0/
data b/.5d0, .12498593597d0, .06880248576d0, .03328355346d0,
1 .00441787012d0/
kay=a(1)
kk=b(1)
eta=1.d0-k*k
peta=eta
do 1 i=2,5
kay=kay+a(i)*peta
kk=kk+b(i)*peta
1 peta=peta*eta
kay=kay-kk*dlog(eta)
return
end
subroutine djelf(sn, cn, dn, x, sck)
c ssp program: finds jacobian elliptic functions sn,cn,dn.
implicit real*8 (a-h,o-z)
dimension ari(12),geo(12)
double precision sn,cn,dn,x,sck,ari,geo,cm,y
c,a,b,c,d
cm=sck
y=x
if(sck)3,1,4
1 d=dexp(x)
a=1.d0/d
b=a+d
cn=2.d0/b
dn=cn
a=(d-a)/2.d0
sn=a*cn
2 return
3 d=1.d0-sck
cm=-sck/d
d=dsqrt(d)
y=d*x
4 a=1.d0
dn=1.d0
do 6 i=1,12
l=i
ari(i)=a
cm=dsqrt(cm)
geo(i)=cm
c=(a+cm)*.5d0
if(dabs(a-cm)-1.d-9*a)7,7,5
5 cm=a*cm
6 a=c
7 y=c*y
sn=dsin(y)
cn=dcos(y)
if(sn)8,13,8
8 a=cn/sn
c=a*c
do 9 i=1,l
k=l-i+1
b=ari(k)
a=c*a
c=dn*c
dn=(geo(k)+a)/(b+a)
9 a=c/b
a=1.d0/dsqrt(c*c+1.d0)
if(sn)10,11,11
10 sn=-a
goto 12
11 sn=a
12 cn=c*sn
13 if(sck)14,2,2
14 a=dn
dn=cn
cn=a
sn=sn/d
return
end